<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>拳头游戏粒子特效</title>
    <style>
        body {
            background-color: #290000;
        }

        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script>
        window.onload = function () {
            const canvas = document.getElementById("canvas");
            const ctx = canvas.getContext("2d");
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
            let particlesArray = [];
            const numberOfParticles = 1000;
            const particleSize = 1;
            const particleSpacing = 1.4;
            const mouseRadius = 70;
            const mouse = { x: null, y: null, radius: mouseRadius };
            window.addEventListener("mousemove", function (event) {
                mouse.x = event.x;
                mouse.y = event.y;
            });
            class Particle {
                constructor(x, y) {
                    this.x = Math.random() * canvas.width;
                    this.y = Math.random() * canvas.height;
                    this.size = particleSize;
                    this.color = "#EB0029";
                    this.baseX = x;
                    this.baseY = y;
                    this.density = Math.random() * 30 + 1;
                }
                draw() {
                    ctx.fillStyle = this.color;
                    ctx.beginPath();
                    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                    ctx.closePath();
                    ctx.fill();
                }
                update() {
                    let dx = mouse.x - this.x;
                    let dy = mouse.y - this.y;
                    let distance = Math.sqrt(dx * dx + dy * dy);
                    let forceDirectionX = dx / distance;
                    let forceDirectionY = dy / distance;
                    let maxDistance = mouse.radius;
                    let force = (maxDistance - distance) / maxDistance;
                    let directionX = forceDirectionX * force * this.density;
                    let directionY = forceDirectionY * force * this.density;
                    if (distance < mouse.radius) {
                        this.x -= directionX;
                        this.y -= directionY;
                    } else {
                        if (this.x !== this.baseX) {
                            let dx = this.x - this.baseX;
                            this.x -= dx / 10;
                        }
                        if (this.y !== this.baseY) {
                            let dy = this.y - this.baseY;
                            this.y -= dy / 10;
                        }
                    }
                }
            }
            async function loadSVG(url) {
                const response = await fetch(url);
                const text = await response.text();
                const parser = new DOMParser();
                const xmlDoc = parser.parseFromString(text, "image/svg+xml");
                const paths = xmlDoc.getElementsByTagName("path");
                return Array.from(paths).map((path) => path.getAttribute("d"));
            }
            function getParticlePositionsFromPathData(pathData) {
                const positions = [];
                const path = new Path2D(pathData);
                const canvasWidth = canvas.width;
                const canvasHeight = canvas.height;
                let minX = canvasWidth,
                    maxX = 0,
                    minY = canvasHeight,
                    maxY = 0;
                for (let y = 0; y < canvasHeight; y += particleSpacing) {
                    for (let x = 0; x < canvasWidth; x += particleSpacing) {
                        if (ctx.isPointInPath(path, x, y)) {
                            positions.push({ x, y });
                            if (x < minX) minX = x;
                            if (x > maxX) maxX = x;
                            if (y < minY) minY = y;
                            if (y > maxY) maxY = y;
                        }
                    }
                }
                return { positions, minX, maxX, minY, maxY };
            }
            async function init() {
                particlesArray = [];
                const svgPaths = await loadSVG(
                    "https://fecoder-pic-1302080640.cos.ap-nanjing.myqcloud.com/Riot_Games_2022.svg"
                );
                let allPositions = [];
                let minX = canvas.width,
                    maxX = 0,
                    minY = canvas.height,
                    maxY = 0;
                svgPaths.forEach((pathData) => {
                    const {
                        positions,
                        minX: pathMinX,
                        maxX: pathMaxX,
                        minY: pathMinY,
                        maxY: pathMaxY,
                    } = getParticlePositionsFromPathData(pathData);
                    allPositions = allPositions.concat(positions);
                    if (pathMinX < minX) minX = pathMinX;
                    if (pathMaxX > maxX) maxX = pathMaxX;
                    if (pathMinY < minY) minY = pathMinY;
                    if (pathMaxY > maxY) maxY = pathMaxY;
                });
                const offsetX = (canvas.width - (maxX - minX)) / 2 - minX;
                const offsetY = (canvas.height - (maxY - minY)) / 2 - minY;
                allPositions = allPositions.map((pos) => ({
                    x: pos.x + offsetX,
                    y: pos.y + offsetY,
                }));
                allPositions.forEach((pos) => {
                    particlesArray.push(new Particle(pos.x, pos.y));
                });
            }
            function animate() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                for (let i = 0; i < particlesArray.length; i++) {
                    particlesArray[i].draw();
                    particlesArray[i].update();
                }
                requestAnimationFrame(animate);
            }
            init();
            animate();
            window.addEventListener("resize", function () {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
                init();
            });
        };
    </script>
</body>

</html>